package morning.cat.feign;

import feign.Client;
import feign.Request;
import feign.Response;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.HashMap;

/**
 * @describe: 类描述信息
 * @author: morningcat.zhang
 * @date: 2019/6/4 2:43 PM
 */
public class MyFeignClient implements Client {

    /**
     * 将Feign的Request实例，转换为HttpClient的HttpRequestBase，再使用CloseableHttpClient来执行请求；
     * 得到响应的HttpResponse实例后，再转换为Feign的Reponse实例返回。
     *
     * @param request
     * @param options
     * @return
     * @throws IOException
     */
    @Override
    public Response execute(Request request, Request.Options options) throws IOException {
        try {
            // 创建一个默认的客户端
            CloseableHttpClient httpclient = HttpClients.createDefault();
            // 获取调用的HTTP方法
            final String method = request.httpMethod().name();

            // 创建一个HttpClient的HttpRequest
            HttpRequestBase httpRequest = new HttpRequestBase() {
                @Override
                public String getMethod() {
                    return method;
                }
            };

            // 设置请求地址
            httpRequest.setURI(new URI(request.url()));
            // 执行请求，获取响应
            HttpResponse httpResponse = httpclient.execute(httpRequest);
            // 获取响应的主体内容
            byte[] body = EntityUtils.toByteArray(httpResponse.getEntity());
            // 将HttpClient的响应对象转换为Feign的Response
            Response response = Response.builder()
                    .body(body)
                    .headers(new HashMap<String, Collection<String>>())
                    .status(httpResponse.getStatusLine().getStatusCode())
                    .request(request)
                    .build();
            return response;
        } catch (Exception e) {
            throw new IOException(e);
        }
    }
}
